import { QueryInterface, Sequelize } from 'sequelize';
import glob from 'glob-promise';
import path from 'path';

const sorter = (a: string, b: string) => {
  const _a = path.basename(a);
  const _b = path.basename(b);
  return _a === _b ? 0 : _a < _b ? -1 : 1;
};

function diff(end: Date, start: Date) {
  return (end.getTime() - start.getTime()) / 1000;
}

function getUpHandler(file: string) {
  return async (queryInterface: QueryInterface) => {
    const name = path.basename(file, path.extname(file));
    const start = new Date();
    console.log(`== ${name}: migrating =======`);
    const { up } = await import(path.join(process.cwd(), file));
    await up(queryInterface, Sequelize);
    const time = diff(new Date(), start);
    console.log(`== ${name}: migrated (${time}s)`);
    console.log('');
  };
}

function getDownHandler(file: string) {
  return async (queryInterface: QueryInterface) => {
    const name = path.basename(file, path.extname(file));
    const start = new Date();
    console.log(`== ${name}: reverting =======`);
    const { down } = await import(path.join(process.cwd(), file));
    await down(queryInterface, Sequelize);
    const time = diff(new Date(), start);
    console.log(`== ${name}: reverted (${time}s)`);
    console.log('');
  };
}

export async function getMigrations(): Promise<any[]> {
  const files = await glob('sequelize/migrations/**/*.ts');

  const sorted = files.sort(sorter);
  // console.log(sorted);
  const migrations: any[] = sorted.map((file) => {
    return {
      name: path.basename(file),
      up: getUpHandler(file),
      down: getDownHandler(file),
    };
  });
  return migrations;
}
